<template>
  <view class="container">
    <!-- 游戏标题 -->
    <view class="game-title">扫雷小游戏</view>

    <!-- 游戏信息区 -->
    <view class="game-info">
      <view class="counter">
        <text class="iconfont icon-bomb"></text>
        <text class="number">{{ mineCount - markedCount | formatNumber }}</text>
      </view>

      <button class="restart-btn" @click="restartGame"
        :class="{ 'game-over': gameStatus === 'lose', 'game-win': gameStatus === 'win' }">
        <text class="iconfont" :class="statusIcon"></text>
      </button>

      <view class="counter">
        <text class="iconfont icon-clock"></text>
        <text class="number">{{ time | formatNumber }}</text>
      </view>
    </view>

    <!-- 难度选择 -->
    <view class="difficulty-selector">
      <button @click="setDifficulty('easy')" :class="{ active: difficulty === 'easy' }">
        初级
      </button>
      <button @click="setDifficulty('medium')" :class="{ active: difficulty === 'medium' }">
        中级
      </button>
      <button @click="setDifficulty('hard')" :class="{ active: difficulty === 'hard' }">
        高级
      </button>
    </view>

    <!-- 游戏棋盘 -->
    <view class="game-board" :style="{ 
      gridTemplateColumns: `repeat(${cols}, ${cellSize}px)`,
      gridGap: `${gap}px`,
      margin: `${gap}px auto`,
      padding: `${gap}px`,
    }">
      <view v-for="(row, rowIndex) in board" :key="rowIndex">
        <view v-for="(cell, colIndex) in row" :key="colIndex" class="cell" :style="{ 
            width: `${cellSize}px`, 
            height: `${cellSize}px`,
          }" :class="[
            cellStatus(cell),
            { 'has-number': cell.revealed && cell.number > 0 },
            `number-${cell.number}`
          ]" @click="handleCellClick(rowIndex, colIndex)" @longpress="handleCellLongPress(rowIndex, colIndex)"
          @touchstart="handleTouchStart" @touchend="handleTouchEnd">
          <template v-if="cell.revealed && cell.number > 0">
            {{ cell.number }}
          </template>
          <template v-if="!cell.revealed && cell.marked">
            <text class="iconfont icon-flag"></text>
          </template>
          <template v-if="gameStatus === 'lose' && cell.isMine && !cell.marked">
            <text class="iconfont icon-bomb"></text>
          </template>
          <template v-if="gameStatus === 'lose' && !cell.isMine && cell.marked">
            <text class="iconfont icon-error"></text>
          </template>
        </view>
      </view>
    </view>

    <!-- 游戏说明 -->
    <view class="game-instructions">
      <view>点击：揭示格子</view>
      <view>长按：标记地雷</view>
    </view>
  </view>
</template>

<script setup>
  import {
    ref,
    computed,
    onMounted,
    onUnmounted
  } from 'vue';

  // 游戏配置 - 不同难度
  const difficulties = {
    easy: {
      rows: 9,
      cols: 9,
      mines: 10
    },
    medium: {
      rows: 16,
      cols: 16,
      mines: 40
    },
    hard: {
      rows: 16,
      cols: 30,
      mines: 99
    }
  };

  // 响应式状态
  const difficulty = ref('easy');
  const board = ref([]);
  const gameStatus = ref('ready'); // ready, playing, win, lose
  const mineCount = ref(difficulties.easy.mines);
  const markedCount = ref(0);
  const time = ref(0);
  const rows = ref(difficulties.easy.rows);
  const cols = ref(difficulties.easy.cols);
  const cellSize = ref(30);
  const gap = ref(2);
  const timer = ref(null);
  const firstClick = ref(true);
  const touchStartTime = ref(0);

  // 计算属性
  const statusIcon = computed(() => {
    switch (gameStatus.value) {
      case 'ready':
      case 'playing':
        return 'icon-smile';
      case 'win':
        return 'icon-cool';
      case 'lose':
        return 'icon-cry';
      default:
        return 'icon-smile';
    }
  });

  // 格式化数字为3位显示
  const formatNumber = (value) => {
    return value.toString().padStart(3, '0');
  };

  // 初始化棋盘
  const initBoard = () => {
    const newBoard = [];
    for (let i = 0; i < rows.value; i++) {
      newBoard[i] = [];
      for (let j = 0; j < cols.value; j++) {
        newBoard[i][j] = {
          isMine: false,
          revealed: false,
          marked: false,
          number: 0
        };
      }
    }
    board.value = newBoard;
  };

  // 随机放置地雷
  const placeMines = (firstRow, firstCol) => {
    let minesPlaced = 0;

    // 确保第一次点击的位置及其周围8格没有地雷
    const safeZone = [];
    for (let i = -1; i <= 1; i++) {
      for (let j = -1; j <= 1; j++) {
        const r = firstRow + i;
        const c = firstCol + j;
        if (r >= 0 && r < rows.value && c >= 0 && c < cols.value) {
          safeZone.push(`${r},${c}`);
        }
      }
    }

    while (minesPlaced < mineCount.value) {
      const row = Math.floor(Math.random() * rows.value);
      const col = Math.floor(Math.random() * cols.value);
      const key = `${row},${col}`;

      // 确保不是第一次点击的安全区且还没放置地雷
      if (!safeZone.includes(key) && !board.value[row][col].isMine) {
        board.value[row][col].isMine = true;
        minesPlaced++;
      }
    }
  };

  // 计算每个格子周围的地雷数
  const calculateNumbers = () => {
    for (let i = 0; i < rows.value; i++) {
      for (let j = 0; j < cols.value; j++) {
        if (!board.value[i][j].isMine) {
          let count = 0;
          // 检查周围8个格子
          for (let di = -1; di <= 1; di++) {
            for (let dj = -1; dj <= 1; dj++) {
              if (di === 0 && dj === 0) continue;

              const ni = i + di;
              const nj = j + dj;

              if (ni >= 0 && ni < rows.value && nj >= 0 && nj < cols.value) {
                if (board.value[ni][nj].isMine) {
                  count++;
                }
              }
            }
          }
          board.value[i][j].number = count;
        }
      }
    }
  };

  // 揭示格子
  const revealCell = (row, col) => {
    // 检查是否已揭示或已标记
    if (board.value[row][col].revealed || board.value[row][col].marked) {
      return;
    }

    // 标记为已揭示
    board.value[row][col].revealed = true;

    // 如果是地雷，游戏结束
    if (board.value[row][col].isMine) {
      gameOver(false);
      return;
    }

    // 如果是空白格（周围没有地雷），递归揭示周围格子
    if (board.value[row][col].number === 0) {
      for (let di = -1; di <= 1; di++) {
        for (let dj = -1; dj <= 1; dj++) {
          if (di === 0 && dj === 0) continue;

          const ni = row + di;
          const nj = col + dj;

          if (ni >= 0 && ni < rows.value && nj >= 0 && nj < cols.value) {
            revealCell(ni, nj);
          }
        }
      }
    }

    // 检查是否获胜
    checkWin();
  };

  // 处理格子点击
  const handleCellClick = (row, col) => {
    // 如果游戏已结束，不响应点击
    if (gameStatus.value === 'win' || gameStatus.value === 'lose') {
      return;
    }

    // 第一次点击
    if (firstClick.value) {
      firstClick.value = false;
      startGame(row, col);
      return;
    }

    // 如果是已标记的格子，不响应点击
    if (board.value[row][col].marked) {
      return;
    }

    revealCell(row, col);
  };

  // 处理格子长按（标记地雷）
  const handleCellLongPress = (row, col) => {
    // 如果游戏已结束或格子已揭示，不响应长按
    if (gameStatus.value === 'win' || gameStatus.value === 'lose' || board.value[row][col].revealed) {
      return;
    }

    // 切换标记状态
    const wasMarked = board.value[row][col].marked;
    board.value[row][col].marked = !wasMarked;

    // 更新标记计数
    markedCount.value += wasMarked ? -1 : 1;

    // 检查是否获胜
    checkWin();
  };

  // 触摸开始事件
  const handleTouchStart = (e) => {
    touchStartTime.value = e.timeStamp;
  };

  // 触摸结束事件
  const handleTouchEnd = (e) => {
    // 快速点击可能会同时触发点击和长按，这里做一下处理
    const touchTime = e.timeStamp - touchStartTime.value;
    if (touchTime < 300) { // 小于300ms视为点击
      // 可以在这里添加点击处理逻辑
    }
  };

  // 开始游戏
  const startGame = (firstRow, firstCol) => {
    gameStatus.value = 'playing';
    placeMines(firstRow, firstCol);
    calculateNumbers();
    revealCell(firstRow, firstCol);
    startTimer();
  };

  // 开始计时器
  const startTimer = () => {
    if (timer.value) {
      clearInterval(timer.value);
    }
    time.value = 0;
    timer.value = setInterval(() => {
      time.value++;
      // 最大计时999秒
      if (time.value >= 999) {
        clearInterval(timer.value);
      }
    }, 1000);
  };

  // 停止计时器
  const stopTimer = () => {
    if (timer.value) {
      clearInterval(timer.value);
      timer.value = null;
    }
  };

  // 检查是否获胜
  const checkWin = () => {
    let revealedCount = 0;
    let correctMarks = 0;

    for (let i = 0; i < rows.value; i++) {
      for (let j = 0; j < cols.value; j++) {
        const cell = board.value[i][j];
        if (cell.revealed && !cell.isMine) {
          revealedCount++;
        }
        if (cell.marked && cell.isMine) {
          correctMarks++;
        }
      }
    }

    // 获胜条件：所有非地雷格子都被揭示 或 所有地雷都被正确标记
    const totalNonMineCells = rows.value * cols.value - mineCount.value;
    if (revealedCount === totalNonMineCells || correctMarks === mineCount.value) {
      gameOver(true);
    }
  };

  // 游戏结束
  const gameOver = (isWin) => {
    gameStatus.value = isWin ? 'win' : 'lose';
    stopTimer();

    // 如果输了，揭示所有地雷
    if (!isWin) {
      for (let i = 0; i < rows.value; i++) {
        for (let j = 0; j < cols.value; j++) {
          const cell = board.value[i][j];
          if (cell.isMine && !cell.marked) {
            cell.revealed = true;
          }
        }
      }
    } else {
      // 如果赢了，把所有地雷都标记出来
      for (let i = 0; i < rows.value; i++) {
        for (let j = 0; j < cols.value; j++) {
          const cell = board.value[i][j];
          if (cell.isMine && !cell.marked) {
            cell.marked = true;
            markedCount.value++;
          }
        }
      }
    }
  };

  // 重新开始游戏
  const restartGame = () => {
    stopTimer();
    initBoard();
    gameStatus.value = 'ready';
    markedCount.value = 0;
    time.value = 0;
    firstClick.value = true;
  };

  // 设置难度
  const setDifficulty = (diff) => {
    difficulty.value = diff;
    rows.value = difficulties[diff].rows;
    cols.value = difficulties[diff].cols;
    mineCount.value = difficulties[diff].mines;

    // 根据难度调整格子大小，确保在各种屏幕上都能显示
    if (diff === 'hard') {
      cellSize.value = 24; // 高级难度格子小一点
    } else {
      cellSize.value = 30;
    }

    restartGame();
  };

  // 获取格子状态的类名
  const cellStatus = (cell) => {
    if (gameStatus.value === 'lose' && cell.isMine) {
      return 'cell-mine';
    }

    if (cell.revealed) {
      return cell.isMine ? 'cell-mine' : 'cell-revealed';
    } else if (cell.marked) {
      return 'cell-marked';
    } else {
      return 'cell-hidden';
    }
  };

  // 初始化
  onMounted(() => {
    initBoard();
  });

  // 组件卸载时清除定时器
  onUnmounted(() => {
    stopTimer();
  });
</script>

<style scoped>
  .container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 16px;
    background-color: #f5f5f5;
    min-height: 100vh;
  }

  .game-title {
    font-size: 24px;
    font-weight: bold;
    margin-bottom: 16px;
    color: #333;
  }

  .game-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    max-width: 500px;
    margin-bottom: 16px;
    padding: 0 8px;
  }

  .counter {
    background-color: #000;
    color: #ff0000;
    padding: 8px;
    border-radius: 4px;
    font-family: monospace;
    display: flex;
    align-items: center;
    min-width: 80px;
    justify-content: center;
  }

  .number {
    font-size: 20px;
    margin-left: 4px;
  }

  .restart-btn {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background-color: #ccc;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    padding: 0;
  }

  .restart-btn.game-over {
    background-color: #ffcccc;
  }

  .restart-btn.game-win {
    background-color: #ccffcc;
  }

  .difficulty-selector {
    display: flex;
    gap: 8px;
    margin-bottom: 16px;
  }

  .difficulty-selector button {
    padding: 6px 12px;
    border-radius: 4px;
    border: 1px solid #ccc;
    background-color: #fff;
  }

  .difficulty-selector button.active {
    background-color: #007aff;
    color: white;
    border-color: #007aff;
  }

  .game-board {
    display: grid;
    background-color: #bbb;
    border: 3px solid #777;
    border-radius: 4px;
  }

  .cell {
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: bold;
    font-size: 16px;
    transition: all 0.2s;
  }

  .cell-hidden {
    background-color: #ccc;
    border-top: 3px solid #fff;
    border-left: 3px solid #fff;
    border-right: 3px solid #777;
    border-bottom: 3px solid #777;
  }

  .cell-revealed {
    background-color: #ccc;
    border: 1px solid #777;
  }

  .cell-marked {
    background-color: #ccc;
    border-top: 3px solid #fff;
    border-left: 3px solid #fff;
    border-right: 3px solid #777;
    border-bottom: 3px solid #777;
    color: #ff0000;
  }

  .cell-mine {
    background-color: #ff0000;
    border: 1px solid #777;
    color: #000;
  }

  .has-number {
    font-size: 14px;
  }

  .number-1 {
    color: #0000ff;
  }

  .number-2 {
    color: #008000;
  }

  .number-3 {
    color: #ff0000;
  }

  .number-4 {
    color: #000080;
  }

  .number-5 {
    color: #800000;
  }

  .number-6 {
    color: #008080;
  }

  .number-7 {
    color: #000000;
  }

  .number-8 {
    color: #808080;
  }

  .game-instructions {
    margin-top: 16px;
    font-size: 14px;
    color: #666;
    display: flex;
    gap: 16px;
  }
</style>